#pragma once 
# include <map>
# include <functional>
# include <Arduino.h>
# include "../ganix/http_server.hpp"
# include "../ganix/wifi.hpp"
# include "message.hpp"
# include "rpc_handler.hpp"
# include "global.hpp"
# include "node_manager.hpp"

class ConnectionManager {
    private:
        ganix::wifi::Mesh *mesh;

        void init_mesh() {
            Serial.println("mesh init start.");

            mesh = new ganix::wifi::Mesh("8266-", WORKER_NAME, "ganix-ama", [](String &message, FloodingMesh &meshInstance){
                //Serial.printf("Received msg:%s\n", message);
                Message msg (message);
                rpc_handler.call(message);
                return true;
            });

            Serial.println("mesh init finish.");
        }

        void mesh_brocast(String message) {
            //Serial.println("brocasting: " + message);
            mesh->brocast(message);
        }

    public:
        ConnectionManager() {}

        void init() {
            init_mesh();
            node_mgr.start([this](Message &message){
                this->call_message_rpc(message);
            });
        };

        void loop() {
            floodingMeshDelay(1);
        };

        void call_message_rpc(Message &message) {
            //Serial.println("sending: "); message.print();
            String target = message.get<String>(TARGET);
            if (target == WORKER_NAME) {
                rpc_handler.call(message); 
                return ;
            }
            if (target == TARGET_BROCAST) {
                rpc_handler.call(message);
            } else if (!node_mgr.valid_node(target)) {
                Serial.printf("on call message, target(%s) not valid.\n", target.c_str());
                message.print();
                return ;
            }
            mesh_brocast(message.to_string());
        }
}conn_mgr;
